package com.szgd.util;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.commons.fileupload.FileItem;
import org.apache.log4j.Logger;

import sun.net.TelnetInputStream;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;

public class FTPUtil {

	private Logger log = Logger.getLogger(FTPUtil.class);
	//创建ftp服务器  
	FtpClient ftpClient; 

	/**  
	 * connectServer  
	 * 连接ftp服务器  
	 * @throws IOException
	 * @param path 文件夹，空代表根目录  
	 * @param password 密码  
	 * @param user    登陆用户  
	 * @param server 服务器地址  
	 */   
	public FtpClient connectServer(String server, String user, String password, String path)   
	{   
		try {
			// server：FTP服务器的IP地址；user:登录FTP服务器的用户名   
			// password：登录FTP服务器的用户名的口令；path：FTP服务器上的路径   
			//ftpClient = new FtpClient();   
			ftpClient = FtpClient.create(server);
			//开启服务  
			//ftpClient.openServer(server);  
			//登录  
			//ftpClient.login(user, password);  
			ftpClient.login(server, null, password); 
			//path是ftp服务下主目录的子目录   
			if (path.length() != 0) 
				//ftpClient.cd(path);
				ftpClient.changeDirectory(path);
			//用2进制上传、下载   
			//ftpClient.binary();
			ftpClient.setBinaryType();
		} catch (Exception e) {
			log.error("ftp链接异常或超时");
		}
		return ftpClient;        
	}   

	public long download(String fileId,String newFileName) throws IOException, FtpProtocolException{
		long result = 0; 
	    TelnetInputStream is = null; 
	    FileOutputStream os = null; 
		try {
			//is=ftpClient.get(fileId);
			is = (TelnetInputStream) ftpClient.getFileStream(fileId);
			File outFile=new File(newFileName);
			os = new FileOutputStream(outFile); 
			byte[] bytes = new byte[1024]; 
		    int c; 
		    while ((c = is.read(bytes)) != -1) { 
	            os.write(bytes, 0, c); 
	            result = result + c; 
	        } 
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if (is != null) { 
				is.close();
	        } 
	        if (os != null) { 
	        	os.close(); 
	        } 
		}
		return result;
	}

	/**  
	 * upload  
	 * 上传文件  
	 * @throws Exception
	 * @return -1 文件不存在  
	 *           -2 文件内容为空  
	 *           >0 成功上传，返回文件的大小  
	 * @param newname 上传后的新文件名  
	 * @param filename 上传的文件  
	 */   
	public boolean upload(String newname,File uploadFile) throws Exception   
	{   
		boolean result = false;   
		//ftp输出流  
		TelnetOutputStream os = null;  
		FileInputStream is = null;   
		try {            
			//ftpclient的put方法 调用后将路径传进去 返回TelnetOutputStream 就可以进行文件上传操作了  
			//os = ftpClient.put(newname); 
			os = (TelnetOutputStream) ftpClient.putFileStream(newname, true);
			is = new FileInputStream(uploadFile);  
			byte[] bytes = new byte[1024];  
			int c;   
			while ((c = is.read(bytes)) != -1) {   
				os.write(bytes, 0, c);   
			} 
			result = true;
		}catch (Exception e) {
			e.printStackTrace();
		} finally {   
			if (is != null) {   
				is.close();   
			}   
			if (os != null) {   
				os.close();   
			}   
		}   
		return result;   
	}  
	public boolean upload(FileItem file,String uuid) throws Exception   {
		InputStream is=null;
		TelnetOutputStream os = null;  
		try{
			is=file.getInputStream();
			//os = ftpClient.put(uuid);   
			os = (TelnetOutputStream) ftpClient.putFileStream(uuid, true);
			byte[] bytes = new byte[1024];  
			int c;   
			while ((c = is.read(bytes)) != -1) {   
				os.write(bytes, 0, c);   
			} 
			return true;
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException("上传ftp文件错误！", e); 
		}finally { 
			if (is != null) {   
				is.close();
			}   
			if (os != null) {   
				os.close();   
			}  
        }
	}

	/**
	 *  判断Ftp目录是否存在,如果不存在则创建目录 
	 *  
	 */
	public boolean createDir(String dirPath,String[] names) throws Exception{  


//		String fullDir = dirPath.substring(0, dirPath.lastIndexOf("/"));  ;  
		String[] dirs = dirPath.split("/");  
		String curDir = "";  
		for (int i = 0; i < dirs.length; i++)  
		{  
			String dir = dirs[i];  
			//如果是以/开始的路径,第一个为空  
			if (dir != null && dir.length() > 0)  
			{  
				try
				{
					curDir += dir+"/";  
					for (int j = 0; j < names.length; j++) {
						if (dir.equals(names[j])) {
							//ftpClient.cd(names[j]);  
							ftpClient.changeDirectory(names[j]);
						}
					}
				} catch (Exception e1)
				{
					//通过远程命令 创建一个files文件夹  
					//ftpClient.sendServer("MKD " + curDir + "\r\n");
					ftpClient.siteCmd("MKD " + curDir + "\r\n");
					createDir(dirPath, names);
					try
					{
						//创建远程文件夹   
						//远程命令包括  
						//USER    PORT    RETR    ALLO    DELE    SITE    XMKD    CDUP    FEAT<br>  
						//      PASS    PASV    STOR    REST    CWD     STAT    RMD     XCUP    OPTS<br>  
						//      ACCT    TYPE    APPE    RNFR    XCWD    HELP    XRMD    STOU    AUTH<br>  
						//      REIN    STRU    SMNT    RNTO    LIST    NOOP    PWD     SIZE    PBSZ<br>  
						//      QUIT    MODE    SYST    ABOR    NLST    MKD     XPWD    MDTM    PROT<br>  
						//           在服务器上执行命令,如果用sendServer来执行远程命令(不能执行本地FTP命令)的话，所有FTP命令都要加上/r/n<br>  
						//                ftpclient.sendServer("XMKD /test/bb/r/n"); //执行服务器上的FTP命令<br>  
						//                ftpclient.readServerResponse一定要在sendServer后调用<br>  
						//                nameList("/test")获取指目录下的文件列表<br>  
						//                XMKD建立目录，当目录存在的情况下再次创建目录时报错<br>  
						//                XRMD删除目录<br>  
						//                DELE删除文件<br>  
						//这个方法必须在 这两个方法中间调用 否则 命令不管用  
						//ftpClient.binary(); 
						//ftpClient.readServerResponse();
					} catch (Exception e)
					{
						e.printStackTrace();
						return false;
					}
					return true;  
				}
			}  
		} 
		return true;
	}  

	/** 
	 * 获取当前目录 
	 *  
	 * @param fc FTP连接对象 
	 * @return 
	 */  
	public String ftpPWD(){  
		try {  
			return ftpClient.getWorkingDirectory();//ftpClient.pwd();  
		} catch (Exception e) {  
			return null;  
		}  
	}  

	/**
	 * 返回FTP目录下的文件列表
	 * @param ftpDirectory
	 * @return
	 */
	public List<String> getFileNameList(String ftpDirectory) 
	{ 
		List<String> list = new ArrayList<String>(); 
		try  
		{ 
			DataInputStream dis = new  DataInputStream(ftpClient.nameList(ftpDirectory)); 
			String filename = ""; 
			while((filename=dis.readLine())!=null)   
			{
				list.add(filename);         
			}   
		} catch (Exception e)  
		{ 
			e.printStackTrace(); 
		} 
		return list; 
	}
	/***
	 * 得到文件流
	 * @param ftpDirectory
	 * @return
	 */
	public DataInputStream getFileInputStream(String ftpDirectory){
		DataInputStream dis = null;
		try  
		{ 
			
			
			 //dis = new  DataInputStream(ftpClient.get(ftpDirectory)); 
			dis = new  DataInputStream(ftpClient.getFileStream(ftpDirectory)); 
		} catch (Exception e)  
		{ 
			e.printStackTrace(); 
		} 
		return dis; 
	}

	/**
	 * 取得指定目录下的所有文件名，不包括目录名称
	 * 分析nameList得到的输入流中的数，得到指定目录下的所有文件名
	 *  @param  fullPath String
	 *  @return  ArrayList
	 *  @throws  Exception
	 */
	public  ArrayList fileNames(String fullPath)  throws  Exception  {
		//ftpClient.ascii();  // 注意，使用字符模式
		ftpClient.setAsciiType();
		TelnetInputStream list  =  (TelnetInputStream) ftpClient.list(fullPath);//ftpClient.nameList(fullPath);
		byte [] names  =   new   byte [ 2048 ];
		int  bufsize  =   0 ;
		bufsize  =  list.read(names,0,names.length);  // 从流中读取
		list.close();
		ArrayList namesList  =   new  ArrayList();
		int  i  =   0 ;
		int  j  =   0 ;
		while  (i  <  bufsize)  {
			if  (names[i]  ==   10 )  {  
				String tempName  =   new  String(names, j, i  -  j);
				namesList.add(tempName);
				j  =  i  +   1 ;  // 上一次位置字符模式
			}
			i  =  i  +   1 ;
		}
		return  namesList;
	}

	/** 
	 * 删除文件 
	 *  
	 * @param fc FTP连接对象 
	 * @param filename 删除的文件名称 
	 * @return 
	 */  
	public boolean ftpDelete(String filename,String path) {  
		try {
			ftpClient.changeDirectory(ftpPWD());  //进入目录
			ftpClient.siteCmd("dele " + filename + "\r\n");   //删除文件
		/*	//判断该目录下是否还存在文件
			String[] paths = path.split("/");
			for (int i = paths.length-1; i >0 ; i--) {
				System.out.println(paths[i]);
				if (paths[i].equals("pub")) {
					continue;
				}
				System.out.println(ftpClient.nameList("/").read());
				if (ftpClient.nameList("/"+paths[i])== null) {
					ftpClient.sendServer("XRMD"+paths[i]+"\r\n");
				}
			}*/
			//ftpClient.readServerResponse();  
			return true;  
		} catch (Exception e) { 
			e.printStackTrace();
			return false;  
		}   
	}  


	/**  
	 * closeServer  
	 * 断开与ftp服务器的链接  
	 * @throws IOException
	 */   
	public void closeServer()   
	{      
		try   
		{   
			if (ftpClient != null)   
			{   
				//ftpClient.closeServer();
				ftpClient.close();
			}   
		} catch (Exception e) {   
			e.printStackTrace();   
		}   
	}
	
	public static void main(String[] args) throws Exception {
		System.out.println(UUID.randomUUID().toString().replace("-", "").toUpperCase());
		FTPUtil ftp = new FTPUtil();
		//连接ftp服务器   
		ftp.connectServer("10.10.10.217", "cdo", "cdo", "/");   
//
		String[] names = new String[]{"file",new SimpleDateFormat("yyyy").format(new Date()),new SimpleDateFormat("MM").format(new Date())};
		//创建一个目录
	//	ftp.createDir("/pub/file",names);
//		//创建一个以年份为名的目录
//		ftp.createDir("/pub/file/"+new SimpleDateFormat("yyyy").format(new Date())+"/",names);
//		//创建一个也月份为名的目录
//		ftp.createDir("/pub/file/"+new SimpleDateFormat("yyyy").format(new Date())+"/"+
//				new SimpleDateFormat("MM").format(new Date())+"/",names);  
//		/**   上传彩铃 */   
//		ftp.upload("D:/CDO.dcp","1234556",new File("D:/CDO.dcp"));   
//		FileUtil.upload();
	}
}
